#pragma once

#include "console_tester.h"

#include "zen_csv.h"
#include "zen_base64.h"
#include "zen_file.h"
#include "zen_md5.h"
#include "zen_random.h"
#include "base64.hpp"

using namespace Zen;

void debug_csv()
{
	Zen::Random random(100);
	Zen::CSVData csv_coder;
	for (int i = 0; i < 10; ++i)
	{
		Zen::CSVData::Row row;
		row.push_back(std::to_string(i));
		for (int k = 0; k < 10; ++k)
		{
			row.push_back(std::to_string(random.Next(10000)));
		}
		csv_coder.GetRows().push_back(std::move(row));
	}
	auto data = csv_coder.Encode();
	cout << data << endl;

	auto file = "temp.csv";
	Zen::File::WriteStringToFile(file, data.data(), data.size());
	cout << "write to file:" << file << endl;
}
AddTest("csv", debug_csv);

Random r;
void debug_base64()
{
	auto en = Zen::Base64::Encode("123");
	cout << "base64(123)=" << en << endl; // MTIz
	cout << "decode=" << Zen::ToString(Zen::Base64::Decode(en)) << endl;
	std::vector<uint8_t> data;
	for (int i = 0; i < 10000; ++i)
	{
		data.push_back((uint8_t)r.Next(255));
		auto r = Zen::Base64::Encode(data.data(), data.size());
		auto r2 = r;
		r2.push_back(0);
		auto s = boost_beast::base64::encode(r2.data(), data.data(), data.size());
		if (s != r.size())
		{
			cout << "error size:" << i << endl;
		}
		else
		{
			r2.resize(s);
			if (r != r2)
			{
				cout << "error result:" << i << endl;
				cout << r << endl;
				cout << r2 << endl;
			}
			else if (i % 100 == 0)
			{
				std::cout << "ok:" << i << endl;
			}
		}
	}
}
AddTest("base64", debug_base64);

#include "md5.hpp"
#include "zen_url.h"

void debug_md5()
{
	std::vector<char> data;
	for (int i = 0; i < 10000; ++i)
	{
		data.push_back(r.Next(255));

		Zen::MD5 md5;
		md5.Start();
		md5.Push(data.data(), data.size());
		auto r = md5.Finish();
		//cout << "md5=" << r << endl;

		boost::uuids::detail::md5 bmd5;
		bmd5.process_bytes(data.data(), data.size());
		union D
		{
			boost::uuids::detail::md5::digest_type dt;
			char r[sizeof(unsigned int) * 4];
		};
		D d{};
		bmd5.get_digest(d.dt);
		auto r2 = Zen::Hex::HexEncode(d.r, std::size(d.r));
		if (r != r2)
		{
			std::cout << "error:" << endl << r << endl;
			cout << r2 << endl;
		}
	}
}

AddTest("md5", debug_md5);
